package org.apache.james.mime4j.decoder;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

public class Base64OutputStream extends FilterOutputStream
{
  static final byte[] CHUNK_SEPARATOR;
  static final int CHUNK_SIZE = 76;
  private static final int MASK_6BITS = 63;
  private static final byte PAD = 61;
  private static final byte[] base64ToInt;
  private static final byte[] intToBase64;
  private byte[] buf;
  private boolean closed;
  private int currentLinePos;
  private final int encodeSize;
  private final int lineLength;
  private final byte[] lineSeparator;
  private int modulus;
  private int pos;
  private final byte[] singleByte;
  private int x;

  static
  {
    byte[] arrayOfByte1 = new byte[2];
    arrayOfByte1[0] = 13;
    arrayOfByte1[1] = 10;
    CHUNK_SEPARATOR = arrayOfByte1;
    byte[] arrayOfByte2 = new byte[64];
    arrayOfByte2[0] = 65;
    arrayOfByte2[1] = 66;
    arrayOfByte2[2] = 67;
    arrayOfByte2[3] = 68;
    arrayOfByte2[4] = 69;
    arrayOfByte2[5] = 70;
    arrayOfByte2[6] = 71;
    arrayOfByte2[7] = 72;
    arrayOfByte2[8] = 73;
    arrayOfByte2[9] = 74;
    arrayOfByte2[10] = 75;
    arrayOfByte2[11] = 76;
    arrayOfByte2[12] = 77;
    arrayOfByte2[13] = 78;
    arrayOfByte2[14] = 79;
    arrayOfByte2[15] = 80;
    arrayOfByte2[16] = 81;
    arrayOfByte2[17] = 82;
    arrayOfByte2[18] = 83;
    arrayOfByte2[19] = 84;
    arrayOfByte2[20] = 85;
    arrayOfByte2[21] = 86;
    arrayOfByte2[22] = 87;
    arrayOfByte2[23] = 88;
    arrayOfByte2[24] = 89;
    arrayOfByte2[25] = 90;
    arrayOfByte2[26] = 97;
    arrayOfByte2[27] = 98;
    arrayOfByte2[28] = 99;
    arrayOfByte2[29] = 100;
    arrayOfByte2[30] = 101;
    arrayOfByte2[31] = 102;
    arrayOfByte2[32] = 103;
    arrayOfByte2[33] = 104;
    arrayOfByte2[34] = 105;
    arrayOfByte2[35] = 106;
    arrayOfByte2[36] = 107;
    arrayOfByte2[37] = 108;
    arrayOfByte2[38] = 109;
    arrayOfByte2[39] = 110;
    arrayOfByte2[40] = 111;
    arrayOfByte2[41] = 112;
    arrayOfByte2[42] = 113;
    arrayOfByte2[43] = 114;
    arrayOfByte2[44] = 115;
    arrayOfByte2[45] = 116;
    arrayOfByte2[46] = 117;
    arrayOfByte2[47] = 118;
    arrayOfByte2[48] = 119;
    arrayOfByte2[49] = 120;
    arrayOfByte2[50] = 121;
    arrayOfByte2[51] = 122;
    arrayOfByte2[52] = 48;
    arrayOfByte2[53] = 49;
    arrayOfByte2[54] = 50;
    arrayOfByte2[55] = 51;
    arrayOfByte2[56] = 52;
    arrayOfByte2[57] = 53;
    arrayOfByte2[58] = 54;
    arrayOfByte2[59] = 55;
    arrayOfByte2[60] = 56;
    arrayOfByte2[61] = 57;
    arrayOfByte2[62] = 43;
    arrayOfByte2[63] = 47;
    intToBase64 = arrayOfByte2;
    byte[] arrayOfByte3 = new byte[123];
    arrayOfByte3[0] = -1;
    arrayOfByte3[1] = -1;
    arrayOfByte3[2] = -1;
    arrayOfByte3[3] = -1;
    arrayOfByte3[4] = -1;
    arrayOfByte3[5] = -1;
    arrayOfByte3[6] = -1;
    arrayOfByte3[7] = -1;
    arrayOfByte3[8] = -1;
    arrayOfByte3[9] = -1;
    arrayOfByte3[10] = -1;
    arrayOfByte3[11] = -1;
    arrayOfByte3[12] = -1;
    arrayOfByte3[13] = -1;
    arrayOfByte3[14] = -1;
    arrayOfByte3[15] = -1;
    arrayOfByte3[16] = -1;
    arrayOfByte3[17] = -1;
    arrayOfByte3[18] = -1;
    arrayOfByte3[19] = -1;
    arrayOfByte3[20] = -1;
    arrayOfByte3[21] = -1;
    arrayOfByte3[22] = -1;
    arrayOfByte3[23] = -1;
    arrayOfByte3[24] = -1;
    arrayOfByte3[25] = -1;
    arrayOfByte3[26] = -1;
    arrayOfByte3[27] = -1;
    arrayOfByte3[28] = -1;
    arrayOfByte3[29] = -1;
    arrayOfByte3[30] = -1;
    arrayOfByte3[31] = -1;
    arrayOfByte3[32] = -1;
    arrayOfByte3[33] = -1;
    arrayOfByte3[34] = -1;
    arrayOfByte3[35] = -1;
    arrayOfByte3[36] = -1;
    arrayOfByte3[37] = -1;
    arrayOfByte3[38] = -1;
    arrayOfByte3[39] = -1;
    arrayOfByte3[40] = -1;
    arrayOfByte3[41] = -1;
    arrayOfByte3[42] = -1;
    arrayOfByte3[43] = 62;
    arrayOfByte3[44] = -1;
    arrayOfByte3[45] = -1;
    arrayOfByte3[46] = -1;
    arrayOfByte3[47] = 63;
    arrayOfByte3[48] = 52;
    arrayOfByte3[49] = 53;
    arrayOfByte3[50] = 54;
    arrayOfByte3[51] = 55;
    arrayOfByte3[52] = 56;
    arrayOfByte3[53] = 57;
    arrayOfByte3[54] = 58;
    arrayOfByte3[55] = 59;
    arrayOfByte3[56] = 60;
    arrayOfByte3[57] = 61;
    arrayOfByte3[58] = -1;
    arrayOfByte3[59] = -1;
    arrayOfByte3[60] = -1;
    arrayOfByte3[61] = -1;
    arrayOfByte3[62] = -1;
    arrayOfByte3[63] = -1;
    arrayOfByte3[64] = -1;
    arrayOfByte3[65] = 0;
    arrayOfByte3[66] = 1;
    arrayOfByte3[67] = 2;
    arrayOfByte3[68] = 3;
    arrayOfByte3[69] = 4;
    arrayOfByte3[70] = 5;
    arrayOfByte3[71] = 6;
    arrayOfByte3[72] = 7;
    arrayOfByte3[73] = 8;
    arrayOfByte3[74] = 9;
    arrayOfByte3[75] = 10;
    arrayOfByte3[76] = 11;
    arrayOfByte3[77] = 12;
    arrayOfByte3[78] = 13;
    arrayOfByte3[79] = 14;
    arrayOfByte3[80] = 15;
    arrayOfByte3[81] = 16;
    arrayOfByte3[82] = 17;
    arrayOfByte3[83] = 18;
    arrayOfByte3[84] = 19;
    arrayOfByte3[85] = 20;
    arrayOfByte3[86] = 21;
    arrayOfByte3[87] = 22;
    arrayOfByte3[88] = 23;
    arrayOfByte3[89] = 24;
    arrayOfByte3[90] = 25;
    arrayOfByte3[91] = -1;
    arrayOfByte3[92] = -1;
    arrayOfByte3[93] = -1;
    arrayOfByte3[94] = -1;
    arrayOfByte3[95] = -1;
    arrayOfByte3[96] = -1;
    arrayOfByte3[97] = 26;
    arrayOfByte3[98] = 27;
    arrayOfByte3[99] = 28;
    arrayOfByte3[100] = 29;
    arrayOfByte3[101] = 30;
    arrayOfByte3[102] = 31;
    arrayOfByte3[103] = 32;
    arrayOfByte3[104] = 33;
    arrayOfByte3[105] = 34;
    arrayOfByte3[106] = 35;
    arrayOfByte3[107] = 36;
    arrayOfByte3[108] = 37;
    arrayOfByte3[109] = 38;
    arrayOfByte3[110] = 39;
    arrayOfByte3[111] = 40;
    arrayOfByte3[112] = 41;
    arrayOfByte3[113] = 42;
    arrayOfByte3[114] = 43;
    arrayOfByte3[115] = 44;
    arrayOfByte3[116] = 45;
    arrayOfByte3[117] = 46;
    arrayOfByte3[118] = 47;
    arrayOfByte3[119] = 48;
    arrayOfByte3[120] = 49;
    arrayOfByte3[121] = 50;
    arrayOfByte3[122] = 51;
    base64ToInt = arrayOfByte3;
  }

  public Base64OutputStream(OutputStream paramOutputStream)
  {
    this(paramOutputStream, 76, CHUNK_SEPARATOR);
  }

  public Base64OutputStream(OutputStream paramOutputStream, int paramInt)
  {
    this(paramOutputStream, paramInt, CHUNK_SEPARATOR);
  }

  public Base64OutputStream(OutputStream paramOutputStream, int paramInt, byte[] paramArrayOfByte)
  {
    super(paramOutputStream);
    this.buf = new byte[1024];
    this.closed = false;
    this.singleByte = new byte[1];
    this.lineLength = paramInt;
    this.lineSeparator = new byte[paramArrayOfByte.length];
    System.arraycopy(paramArrayOfByte, 0, this.lineSeparator, 0, paramArrayOfByte.length);
    if (paramInt > 0)
    {
      this.encodeSize = (4 + paramArrayOfByte.length);
      if (!(containsBase64Byte(paramArrayOfByte)))
        return;
    }
    try
    {
      str = new String(paramArrayOfByte, "UTF-8");
      throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + str + "]");
      this.encodeSize = 4;
    }
    catch (UnsupportedEncodingException localUnsupportedEncodingException)
    {
      while (true)
        str = new String(paramArrayOfByte);
    }
  }

  private static boolean containsBase64Byte(byte[] paramArrayOfByte)
  {
    int j;
    int i = 0;
    if (i < paramArrayOfByte.length)
      if (isBase64(paramArrayOfByte[i]))
        j = 1;
    while (true)
    {
      while (true)
      {
        return j;
        ++i;
      }
      j = 0;
    }
  }

  private void flushBuffer()
    throws IOException
  {
    if (this.pos > 0)
    {
      this.out.write(this.buf, 0, this.pos);
      this.pos = 0;
    }
  }

  public static boolean isBase64(byte paramByte)
  {
    int i;
    if ((paramByte == 61) || ((paramByte >= 0) && (paramByte < base64ToInt.length) && (base64ToInt[paramByte] != -1)))
      i = 1;
    while (true)
    {
      return i;
      i = 0;
    }
  }

  private void resizeBuf()
  {
    byte[] arrayOfByte = new byte[2 * this.buf.length];
    System.arraycopy(this.buf, 0, arrayOfByte, 0, this.buf.length);
    this.buf = arrayOfByte;
  }

  // ERROR //
  public void close()
    throws IOException
  {
    // Byte code:
    //   0: aload_0
    //   1: getfield 163	org/apache/james/mime4j/decoder/Base64OutputStream:closed	Z
    //   4: ifeq +4 -> 8
    //   7: return
    //   8: aload_0
    //   9: aload_0
    //   10: getfield 165	org/apache/james/mime4j/decoder/Base64OutputStream:singleByte	[B
    //   13: iconst_0
    //   14: bipush 255
    //   16: invokevirtual 234	org/apache/james/mime4j/decoder/Base64OutputStream:write	([BII)V
    //   19: aload_0
    //   20: invokevirtual 237	org/apache/james/mime4j/decoder/Base64OutputStream:flush	()V
    //   23: aload_0
    //   24: iconst_1
    //   25: putfield 163	org/apache/james/mime4j/decoder/Base64OutputStream:closed	Z
    //   28: goto -21 -> 7
    //   31: astore_1
    //   32: aload_0
    //   33: iconst_1
    //   34: putfield 163	org/apache/james/mime4j/decoder/Base64OutputStream:closed	Z
    //   37: aload_1
    //   38: athrow
    //
    // Exception table:
    //   from	to	target	type
    //   8	23	31	finally
  }

  public void flush()
    throws IOException
  {
    flushBuffer();
    this.out.flush();
  }

  public void write(int paramInt)
    throws IOException
  {
    this.singleByte[0] = (byte)paramInt;
    write(this.singleByte, 0, 1);
  }

  public void write(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
    throws IOException
  {
    label161: int j;
    if (this.closed)
      throw new IOException("Base64OutputStream has been closed");
    if (paramArrayOfByte == null)
      throw new NullPointerException();
    if (paramInt2 < 0)
    {
      this.closed = true;
      if (this.buf.length - this.pos < this.encodeSize)
        resizeBuf();
      switch (this.modulus)
      {
      default:
        if (this.lineLength <= 0)
          break label161;
        System.arraycopy(this.lineSeparator, 0, this.buf, this.pos, this.lineSeparator.length);
        this.pos += this.lineSeparator.length;
        System.arraycopy(this.lineSeparator, 0, this.buf, this.pos, this.lineSeparator.length);
        this.pos += this.lineSeparator.length;
      case 1:
      case 2:
      }
    }
    while (true)
    {
      do
      {
        while (true)
        {
          while (true)
          {
            flushBuffer();
            return;
            byte[] arrayOfByte9 = this.buf;
            int i10 = this.pos;
            this.pos = (i10 + 1);
            arrayOfByte9[i10] = intToBase64[(0x3F & this.x >> 2)];
            byte[] arrayOfByte10 = this.buf;
            int i11 = this.pos;
            this.pos = (i11 + 1);
            arrayOfByte10[i11] = intToBase64[(0x3F & this.x << 4)];
            byte[] arrayOfByte11 = this.buf;
            int i12 = this.pos;
            this.pos = (i12 + 1);
            arrayOfByte11[i12] = 61;
            byte[] arrayOfByte12 = this.buf;
            int i13 = this.pos;
            this.pos = (i13 + 1);
            arrayOfByte12[i13] = 61;
          }
          byte[] arrayOfByte5 = this.buf;
          int i6 = this.pos;
          this.pos = (i6 + 1);
          arrayOfByte5[i6] = intToBase64[(0x3F & this.x >> 10)];
          byte[] arrayOfByte6 = this.buf;
          int i7 = this.pos;
          this.pos = (i7 + 1);
          arrayOfByte6[i7] = intToBase64[(0x3F & this.x >> 4)];
          byte[] arrayOfByte7 = this.buf;
          int i8 = this.pos;
          this.pos = (i8 + 1);
          arrayOfByte7[i8] = intToBase64[(0x3F & this.x << 2)];
          byte[] arrayOfByte8 = this.buf;
          int i9 = this.pos;
          this.pos = (i9 + 1);
          arrayOfByte8[i9] = 61;
        }
        if ((paramInt1 < 0) || (paramInt2 < 0) || (paramInt1 + paramInt2 < 0))
          throw new IndexOutOfBoundsException();
        if ((paramInt1 > paramArrayOfByte.length) || (paramInt1 + paramInt2 > paramArrayOfByte.length))
          throw new IndexOutOfBoundsException();
      }
      while (paramInt2 <= 0);
      int i = 0;
      j = paramInt1;
      while (true)
      {
        if (i >= paramInt2)
          break label822;
        if (this.buf.length - this.pos < this.encodeSize)
          resizeBuf();
        int k = 1 + this.modulus;
        this.modulus = k;
        this.modulus = (k % 3);
        int l = j + 1;
        int i1 = paramArrayOfByte[j];
        if (i1 < 0);
        this.x = ((i1 += 256) + (this.x << 8));
        if (this.modulus == 0)
        {
          byte[] arrayOfByte1 = this.buf;
          int i2 = this.pos;
          this.pos = (i2 + 1);
          arrayOfByte1[i2] = intToBase64[(0x3F & this.x >> 18)];
          byte[] arrayOfByte2 = this.buf;
          int i3 = this.pos;
          this.pos = (i3 + 1);
          arrayOfByte2[i3] = intToBase64[(0x3F & this.x >> 12)];
          byte[] arrayOfByte3 = this.buf;
          int i4 = this.pos;
          this.pos = (i4 + 1);
          arrayOfByte3[i4] = intToBase64[(0x3F & this.x >> 6)];
          byte[] arrayOfByte4 = this.buf;
          int i5 = this.pos;
          this.pos = (i5 + 1);
          arrayOfByte4[i5] = intToBase64[(0x3F & this.x)];
          this.currentLinePos = (4 + this.currentLinePos);
          if ((this.lineLength > 0) && (this.lineLength <= this.currentLinePos))
          {
            System.arraycopy(this.lineSeparator, 0, this.buf, this.pos, this.lineSeparator.length);
            this.pos += this.lineSeparator.length;
            this.currentLinePos = 0;
          }
        }
        ++i;
        label822: j = l;
      }
    }
  }
}